# -*- python -*-
# ex: set syntax=python:

# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This is the buildmaster config file for the 'chromium' bot. It must
# be installed as 'master.cfg' in your buildmaster's base directory
# (although the filename can be changed with the --basedir option to
# 'mktap buildbot master').

# It has one job: define a dictionary named BuildmasterConfig. This
# dictionary has a variety of keys to control different aspects of the
# buildmaster. They are documented in docs/config.xhtml .

# This file follows this naming convention:
# Factories: f_cr_rel_[type]
# Builders:  b_chromium_rel_[os]_[type]
# BuildDir:  chromium-rel-[os]-[type]
#
# os = xp/vista/linux/mac
# type = perf

from buildbot.scheduler import Scheduler
from buildbot.scheduler import Triggerable

from common import chromium_utils

from master import chromium_notifier
from master import gitiles_poller
from master import master_config
from master import master_utils
from master import slaves_list
from master.factory import annotator_factory

import config
import master_site_config

ActiveMaster = master_site_config.ChromiumPerfFyi


# Enable MAIL_NOTIFIER in production to send alerts.
MAIL_NOTIFIER = ActiveMaster.is_production_host

# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}

# 'slavePortnum' defines the TCP port to listen on. This must match the value
# configured into the buildslaves (with their --master option)
c['slavePortnum'] = ActiveMaster.slave_port

# Disable compression for the stdio files.
c['logCompressionLimit'] = False

# Load the list of slaves.
slaves = slaves_list.SlavesList('slaves.cfg', 'ChromiumPerfFyi')

config.DatabaseSetup(c, require_dbconfig=ActiveMaster.is_production_host)

def recipe_factory(recipe):
  f_annotations = annotator_factory.AnnotatorFactory(ActiveMaster)
  return f_annotations.BaseFactory(recipe=recipe)


# ------------------------------------------------------------------------------
# Change Sources.

# Polls config.Master.trunk_url for changes
master_poller = gitiles_poller.GitilesPoller(
    'https://chromium.googlesource.com/chromium/src')

c['change_source'] = [master_poller]

# End Change Sources.
# ------------------------------------------------------------------------------


# ------------------------------------------------------------------------------
# Schedulers.

## configure the Schedulers

# "FYI" is part of the Win builder name to avoid overwriting the main perf
# waterfall's Win builds. It should be removed once this builder is migrated to
# chromium.perf.
s_chromium = Scheduler(name='chromium',
                       branch='master',
                       treeStableTimer=60,
                       builderNames=['android_oilpan_builder',
                                     'android_webview_aosp_perf',
                                     'Linux Oilpan Builder',
                                     'Win x64 FYI Builder',
                                     'Win Clang Builder',
                                    ])

s_chromium_android_oilpan_rel_trigger = Triggerable('androidrel_oilpan',
                                             ['android_nexus5_oilpan_perf',
                                             ])

s_chromium_linux_oilpan_rel_trigger = Triggerable(
    'linuxrel_oilpan',
    ['Linux Oilpan Perf (1)',
     'Linux Oilpan Perf (2)',
     'Linux Oilpan Perf (3)',
     'Linux Oilpan Perf (4)',
     'Linux Large Profile Generator Perf',
])

s_chromium_winrel_x64_trigger = Triggerable('winrel_x64',
                                            ['Win 7 Intel GPU Perf (Xeon)',
                                             'Win Large Profile Generator Perf',
                                            ])

s_chromium_win_clang_trigger = Triggerable('win_clang',
                                           ['Win Clang Perf'])

c['schedulers'] = [s_chromium,
                   s_chromium_android_oilpan_rel_trigger,
                   s_chromium_linux_oilpan_rel_trigger,
                   s_chromium_winrel_x64_trigger,
                   s_chromium_win_clang_trigger,
                  ]

# End Schedulers.
# ------------------------------------------------------------------------------


c['builders'] = []
# ----------------------------------------------------------------------------
# BUILDER DEFINITIONS

# The 'builders' list defines the Builders. Each one is configured with a
# dictionary, using the following keys:
#  name (required): the name used to describe this bilder
#  builddir (required): which subdirectory to run the builder in
#  factory (required): a BuildFactory to define how the build is run
#  periodicBuildTime (optional): if set, force a build every N seconds
#  category (optional): it is not used in the normal 'buildbot' meaning. It is
#                       used by gatekeeper to determine which steps it should
#                       look for to close the tree.
#

# 1. Builders

b_chromium_rel_android_oilpan_builder = {'name': 'android_oilpan_builder',
  'factory': annotator_factory.AnnotatorFactory(ActiveMaster).BaseFactory(
      recipe='android/builder',
      triggers=['androidrel_oilpan']),
  'category': '1builders|android',
}

b_chromium_rel_linux_oilpan_builder = {'name': 'Linux Oilpan Builder',
  'builddir': 'chromium-rel-linux-oilpan',
  'factory': annotator_factory.AnnotatorFactory(ActiveMaster).BaseFactory(
      recipe='chromium',
      triggers=['linuxrel_oilpan']),
  'category': '1builders|linux',
  'auto_reboot': False,
}

b_chromium_rel_win_x64_builder = {'name': 'Win x64 FYI Builder',
  'builddir': 'chromium-rel-x64-fyi-builder',
  'factory': annotator_factory.AnnotatorFactory(ActiveMaster).BaseFactory(
      recipe='chromium',
      triggers=['winrel_x64'],
      timeout=7200),
  'category': '1builders|windows',
  'auto_reboot': False,
}

# 2. Android

b_chromium_rel_android_nexus5 = {'name': 'android_nexus5_oilpan_perf',
  'factory': recipe_factory('android/perf'),
  'category': '2android|builder_testers',
}

b_webview_aosp_android = {'name': 'android_webview_aosp_perf',
  'factory': recipe_factory('android_webview_aosp_perf'),
  'category': '2android|builder_testers',
}

c['builders'] = [
  b_chromium_rel_android_oilpan_builder,
  b_chromium_rel_android_nexus5,
  b_chromium_rel_linux_oilpan_builder,
  b_chromium_rel_win_x64_builder,
  b_webview_aosp_android,
]

# 3. Windows

c['builders'].append({'name': 'Win 7 Intel GPU Perf (Xeon)',
    'factory': recipe_factory('chromium'),
    'category': '3windows|builder_testers',
    })

# 4. Mac

# 5. Linux

for i in range(0, 4):
  c['builders'].append({
    'name': 'Linux Oilpan Perf (%d)' % (i + 1),
    'factory': recipe_factory('chromium'),
    'category': '5linux|builder_testers',
    })

# 6. Win Clang

b_chromium_win_clang_builder = {
  'name': 'Win Clang Builder',
  'factory': annotator_factory.AnnotatorFactory(ActiveMaster).BaseFactory(
      recipe='chromium',
      triggers=['win_clang']),
  'category': '6win clang|builders',
  'auto_reboot': False,
}

b_chromium_win_clang_perf = {
  'name': 'Win Clang Perf',
  'factory': recipe_factory('chromium'),
  'category': '6win clang|builder_testers',
}

c['builders'].append(b_chromium_win_clang_builder)
c['builders'].append(b_chromium_win_clang_perf)

# 7. Large Profile Generator

c['builders'].append({'name': 'Win Large Profile Generator Perf',
  'factory': annotator_factory.AnnotatorFactory(ActiveMaster).BaseFactory(
      recipe='perf/telemetry_generate_large_profile',
      timeout=24 * 3600),
  'category': '7large profile generator|testers',
})

c['builders'].append({'name': 'Linux Large Profile Generator Perf',
  'factory': annotator_factory.AnnotatorFactory(ActiveMaster).BaseFactory(
      recipe='perf/telemetry_generate_large_profile',
      timeout=24 * 3600),
  'category': '7large profile generator|testers',
})


####### BUILDSLAVES

# Associate the slaves to the manual builders. The configuration is in
# slaves.cfg.
for builder in c['builders']:
  builder['slavenames'] = slaves.GetSlavesName(builder=builder['name'])

# The 'slaves' list defines the set of allowable buildslaves. List all the
# slaves registered to a builder. Remove dupes.
c['slaves'] = master_utils.AutoSetupSlaves(c['builders'],
                                           config.Master.GetBotPassword())
master_utils.VerifySetup(c, slaves)


####### STATUS TARGETS

# the 'buildbotURL' string should point to the location where the buildbot's
# internal web server (usually the html.Waterfall page) is visible. This
# typically uses the port number set in the Waterfall 'status' entry, but
# with an externally-visible host name which the buildbot cannot figure out
# without some help.

#Must come before AutoSetupMaster().
c['buildbotURL'] = ActiveMaster.buildbot_url

# Adds common status and tools to this master.
master_utils.AutoSetupMaster(c, ActiveMaster,
    public_html='../master.chromium/public_html',
    templates=['./templates', '../master.chromium/templates'],
    tagComparator=master_poller.comparator,
    enable_http_status_push=ActiveMaster.is_production_host)

# Add more.

if MAIL_NOTIFIER:
  c['status'].append(chromium_notifier.ChromiumNotifier(
      fromaddr=ActiveMaster.from_address,
      exclusions={},
      relayhost=config.Master.smtp,
      status_header='FYI Perf alert on "%(builder)s":\n%(steps)s',
      subject='%(projectName)s %(builder)s %(result)s',
      extraRecipients=[],
      lookup=master_utils.FilterDomain(),
      sheriffs=[''],
      public_html='../master.chromium/public_html',
      forgiving_steps=[],
      use_getname=True))

####### PROJECT IDENTITY

# the 'projectName' string will be used to describe the project that this
# buildbot is working on. For example, it is used as the title of the
# waterfall HTML page. The 'projectURL' string will be used to provide a link
# from buildbot HTML pages to your project's home page.

c['projectName'] = ActiveMaster.project_name
c['projectURL'] = config.Master.project_url
